import { invoke } from "@tauri-apps/api/core";

// Simple LRU cache implementation for small key space
class LRUCache {
  constructor(limit = 100) {
    this.limit = limit;
    this.map = new Map(); // key -> { value, time }
  }
  get(key) {
    if (!this.map.has(key)) return undefined;
    const v = this.map.get(key);
    this.map.delete(key);
    this.map.set(key, v);
    return v.value;
  }
  set(key, value) {
    if (this.map.has(key)) this.map.delete(key);
    this.map.set(key, { value });
    if (this.map.size > this.limit) {
      const oldestKey = this.map.keys().next().value;
      this.map.delete(oldestKey);
    }
  }
  clear() {
    this.map.clear();
  }
}

const historyContentCache = new LRUCache(200);

export async function setModelConfig(key, config) {
  return invoke("set_model_config", { key, config });
}

export async function getModelConfig(key) {
  return invoke("get_model_config", { key });
}

export async function listModelKeys() {
  try { return await invoke("list_model_keys"); } catch { return []; }
}

export async function deleteModelConfig(key) {
  return invoke("delete_model_config", { key });
}

export async function chat(request) {
  // request: { key, messages, temperature?, max_tokens?, tools?, tool_choice? }
  return invoke("chat", { req: request });
}

export async function setAppSetting(key, value) {
  return invoke("set_app_setting", { key, value });
}

export async function getAppSetting(key) {
  return invoke("get_app_setting", { key });
}

export async function formatCode(language, content, pathHint) {
  return invoke("format_code", { language, content, pathHint });
}

export async function runCommand(cmd, cwd) {
  return invoke("run_command", { cmd, cwd });
}

// PTY APIs
export async function ptySpawn(cwd, cols, rows, program, args) {
  return invoke("pty_spawn", { cwd, cols, rows, program, args });
}
export async function ptyResize(id, cols, rows) {
  return invoke("pty_resize", { id, cols, rows });
}
export async function ptyWrite(id, data) {
  return invoke("pty_write", { id, data });
}
export async function ptyRead(id) {
  return invoke("pty_read", { id });
}
export async function ptyKill(id) {
  return invoke("pty_kill", { id });
}

export async function listShells() {
  return invoke("list_shells", {});
}

export async function get_timeline(path) {
  return invoke("get_timeline", { path });
}

export async function save_local_history(path, content) {
  // Invalidate cache entries for this path since history content changed
  // We keep it simple: clear entire cache to avoid partial stale entries
  historyContentCache.clear();
  return invoke("save_local_history", { filePath: path, content });
}

export async function getGitHistoryContent(path, id) {
  return invoke("get_git_history_content", { path, id });
}

export async function getLocalHistoryContent(path, id) {
  const key = `${path}::${id}`;
  const cached = historyContentCache.get(key);
  if (cached !== undefined) return cached;
  const res = await invoke("get_local_history_content", { filePath: path, id });
  historyContentCache.set(key, res);
  return res;
}

export async function localHistoryRestore(path, content) {
  return invoke("local_history_restore", { path, content });
}

// History configuration APIs
export async function setHistoryConfig(key, value) {
  return invoke("set_history_config", { key, value });
}

export async function getHistoryConfigValue(key) {
  return invoke("get_history_config_value", { key });
}

export async function cleanupAllHistory() {
  // Cleaning all history also invalidates cache
  historyContentCache.clear();
  return invoke("cleanup_all_history");
}


